﻿--NPC商店子子系统消息处理实现 

--#include "data\config\store\NPCStore.lua" once
--#include "data\config\store\RenownShopConfig.lua" once
--#include "data\functions\NpcTradeEventFunc.lua" once

local PriceRatio = 10 --购买价格为出售价格的PriceRatio倍

NPCTradeBuyLimitDataNotice = function (sysarg, itemId, itemNum)
	local npack = DataPack.allocPacket(sysarg,LogicCmd.npcTradeSys.sysId,LogicCmd.npcTradeSys.sub.sNpcTradeBuyLimitDataNotice)  --申请一个数据包
	if (npack == nil) then return end
	DataPack.writeShort(npack,itemId)
	DataPack.writeUInt(npack,itemNum)
	DataPack.flush(npack)
end


GetNPCTradeBuyLimitState = function ( sysarg, config, buyNum)
	local aSvar = Actor.getStaticVar(sysarg)
	if not aSvar.npcTradeLimit then
		aSvar.npcTradeLimit  = {}
	end
	if not aSvar.npcTradeLimit[config.itemId] then
		aSvar.npcTradeLimit[config.itemId] = {} 
	end
	if not aSvar.npcTradeLimit[config.itemId].count then
		aSvar.npcTradeLimit[config.itemId].count = 0
	end
	if aSvar.npcTradeLimit[config.itemId].count + buyNum > config.limitNum then
		Actor.sendTipmsg( sysarg, string.format(Lang.ScriptTips.NpcTrade002, config.limitNum, config.limitNum - aSvar.npcTradeLimit[config.itemId].count),ttFlyTip )
		return false
	end
	return true
end

AddNPCTradeBuyLimitCount = function (sysarg, config, buyNum)
	if config.limitNum and config.limitNum > 0 then
		local aSvar = Actor.getStaticVar(sysarg)
		if not aSvar.npcTradeLimit then
			aSvar.npcTradeLimit  = {}
		end
		if not aSvar.npcTradeLimit[config.itemId] then
			aSvar.npcTradeLimit[config.itemId] = {} 
		end
		if not aSvar.npcTradeLimit[config.itemId].count then
			aSvar.npcTradeLimit[config.itemId].count = 0
		end

		aSvar.npcTradeLimit[config.itemId].count = buyNum + aSvar.npcTradeLimit[config.itemId].count

		if not aSvar.npcTradeLimit[config.itemId].time then
			local openDay = System.getDaysSinceOpenServer()
			local nDayInternal = 86400
			local nPassTime
			if openDay > 0 and config.updateTime > 0 then
				local nPastDays = (openDay - 1) % config.updateTime
				nPassTime = (config.updateTime - nPastDays)* nDayInternal + System.getToday()
			else
				nPassTime = nDayInternal + System.getToday()
			end
			aSvar.npcTradeLimit[config.itemId].time = nPassTime
		end

		NPCTradeBuyLimitDataNotice(sysarg, config.itemId, aSvar.npcTradeLimit[config.itemId].count)
	end 
end

--购买
NPCTradeBuy = function ( sysarg, args )
  	local buyitemid = args[1]  --购买的物品ID
  	local amount = args[2] --物品的数目 
  	local npdId =  args[3] --npcID

  	--[[
	--判断是否在王城区域
	if (Actor.getSceneId(sysarg) == 6 or Actor.getSceneId(sysarg) == 7) then 
		Actor.sendTipmsg(sysarg,Lang.ScriptTips.NpcTrade001,ttFlyTip) 
		return 
	end
	]]

	if amount <= 0 then return false end


  	if ( Actor.canAddItem( sysarg, buyitemid, amount ) == false ) then
	  	Actor.sendTipmsg( sysarg,Lang.ScriptTips.n00006,ttFlyTip )
   		return
  	end

--	--如果是随身背包的话，需要额外的比例 
--	if(npdId ==0) then
--		dprice = dprice * 1.5; 
--	end
		
	--判断购买的物品是否出售
	--解决BUG:出现1个区玩家通过外挂通过NPC购买道具接口购买元宝票，原因是购买的东西没判断是否在配置表里
	--local nConfig = NPCStoreConfig[npdId+1]
	local nConfig = nil
	table.foreachi( NPCStore, function( i, v ) if ( v.npcid == npdId ) then nConfig = v end end )

	local openDay = System.getDaysSinceOpenServer()

	local config
		
	if nConfig == nil then return end
	local bIsExist = false
	local len_c_pack = table.getn(nConfig)
	for i = 1, len_c_pack do
		local s = nConfig[i]
		local silen = table.getn(s.items)
		for x = 1, silen do
			if buyitemid == s.items[x].itemId and openDay >= s.items[x].dayslimit[1] and 
				((s.items[x].dayslimit[2] ~= -1 and openDay <= s.items[x].dayslimit[2]) or s.items[x].dayslimit[2] == -1) then
				bIsExist = true
				config = s.items[x]
				break
			end
		end
	end

	if bIsExist == false then 
		print("err npcstore not exist! buyitemid = "..buyitemid..", npdId = "..npdId)
		return 
	end
	if  not config then
		return
	end

	

	if npdId == 0 and config.limitNum > 0 then
		if not GetNPCTradeBuyLimitState(sysarg, config, amount) then
			return
		end
	end
	 
	local itemname = Item.getItemName(buyitemid)
	--local totalCount =   dprice * amount 

	--[[
	
	local flag = 0
	if Actor.getIntProperty( sysarg, moneyTypeMap[dtype] ) < totalCount  then
		Actor.sendTipmsg( sysarg, Lang.ScriptTips.n00007,ttFlyTip )
		return false
	else 
		if Actor.changeMoney( sysarg, dtype, -totalCount ,GameLog.clShopBuyMoney,itemname) == false  then
			return false
		end
	end
	]]


	if CheckConsumeCond( sysarg, config.consumes, amount ) ~= true then 
		--Actor.sendTipmsg( sysarg, Lang.ScriptTips.n00007,ttFlyTip )
		return false
	end

	if not DoConsumeCond( sysarg, config.consumes, amount, GameLog.clShopBuyMoney, itemname ) then
		return
	end

	if  npdId == 0 and config.limitNum > 0 then
		AddNPCTradeBuyLimitCount(sysarg, config, amount)
	end

	Actor.addItem( sysarg, buyitemid, 0, 0, amount ,1,0,itemname,7);
	--Actor.triggerQuestEvent( sysarg, 127, 50091, 1 )    --购买任务一个物品就可完成
end

-------------------------------------------------------------------------------------------------
--售卖
NPCTradeSell = function ( sysarg, args )
	local ritemguid = args[1] --购回的物品GUID
	local npdId  = args[2]    --回购的NPCid 
  	local sellitemptr = Item.getBagItemPtrByGuid( sysarg, args[1] )
  	if(sellitemptr ==nil) then return end   --找不到这件物品 
	  
  	local pid = Actor.getIntProperty( sysarg, PROP_ENTITY_ID )
	 	local itemid =Item.getItemProperty( sysarg, sellitemptr, Item.ipItemID, 0 )
  	if ( Item.getItemPropertyById( itemid, Item.ipItemDenySell ) == 1 ) then
		return
	end
	local dprice = Item.getItemPropertyById( itemid, Item.ipItemDealMoneyCount )
	 
	local itemtype = Item.getItemProperty( sysarg, sellitemptr, Item.ipItemType, 0 )
	  
	if itemtype == Item.itMine then	--矿物特殊处理
		local dua = Item.getItemProperty(sysarg, sellitemptr, Item.ipItemDua, 0)
		local maxdua = Item.getItemProperty(sysarg, sellitemptr, Item.ipItemDuaMax, 0)
		dprice = math.ceil(dprice * (dua/maxdua))
	end
	local dtype = Item.getItemPropertyById( itemid, Item.ipItemDealMoneyType )
	local amount = Item.getItemProperty( sysarg, sellitemptr, Item.ipItemCount, 0 )
	--print(dprice,amount)
    --卖出
	local removeresult = Item.removeItem( sysarg, sellitemptr, amount, "Npc sell.", 8, false )

	local itemname = Item.getItemName(itemid)

	local gainresult = Actor.changeMoney( sysarg, dtype, dprice*amount ,GameLog.clShopSellMoney,itemname)
	
	if removeresult then
	  	local sellresult = Item.addSellItem(sysarg,sellitemptr,amount)
	end
	--发一个数据包告诉客户端成功卖出一件物品 
	local npack = DataPack.allocPacket(sysarg,LogicCmd.npcTradeSys.sysId,LogicCmd.npcTradeSys.sub.sNpcTradeShopSell)  --申请一个数据包
	if (npack == nil) then
		return
	end
	DataPack.writeChar(npack,npdId)
	DataPack.writeDouble(npack,ritemguid)
	DataPack.flush(npack)
end

---------------------------------------------------------------------------------
--购回
NPCTradeRepurchase = function ( sysarg, args )

	--[[
	--判断是否在王城里
	if (Actor.getSceneId(sysarg) == 6 or Actor.getSceneId(sysarg) == 7) then Actor.sendTipmsg(sysarg,Lang.ScriptTips.NpcTrade001,ttFlyTip) return end
	]]

	local ritemguid = args[1] --购回的物品GUID
	local npdId  = args[2]    --回购的NPCid 
	local pid = Actor.getIntProperty( sysarg, PROP_ENTITY_ID )

	--print("111112----"..ritemguid)
	--购回的物品指针
	local ritemptr = Item.getSellItem(sysarg,ritemguid)
	if ritemptr == nil then return end
	local ritemid = Item.getItemProperty( sysarg, ritemptr, Item.ipItemID, 0 )
	local dprice = Item.getItemProperty( sysarg, ritemptr, Item.ipItemDealMoneyCount, 0 )

	local itemtype = Item.getItemProperty( sysarg, ritemptr, Item.ipItemType, 0 )
	if itemtype == Item.itMine then	--矿物特殊处理
		local dua = Item.getItemProperty(sysarg, ritemptr, Item.ipItemDua, 0)
		local maxdua = Item.getItemProperty(sysarg, ritemptr, Item.ipItemDuaMax, 0)
		dprice = math.ceil(dprice * (dua/maxdua))
	end

	local dprice = dprice

	local amount = Item.getItemProperty(sysarg,ritemptr,Item.ipItemCount,0)
	local dtype = Item.getItemProperty( sysarg, ritemptr, Item.ipItemDealMoneyType, 0 )
	--if dtype ~= 1 then
	--dtype = 1
	--end
	if ( Actor.canAddItem( sysarg, ritemid, amount ) == false ) then
		Actor.sendTipmsg( sysarg, Lang.ScriptTips.n00006,ttFlyTip )
		return
	end

	local bagCount = Item.getBagEmptyGridCount(sysarg)
	if bagCount < 1 then
		Actor.sendTipmsg( sysarg, Lang.ScriptTips.n00006,ttFlyTip )
		return
	end
	local    totalCount =   dprice *   amount *10--这里防止玩家出现问题，在随身的背包里回购的价格必须是普通价格的2.5倍
	local itemname = Item.getItemName(ritemid) 
	--[[
	if(npdId ==0) then --是随身商店的回购的价格都要1.5倍 
	totalCount = totalCount * 2.5 --如果是在NPC 
	end
	--]]
	if ( Actor.getIntProperty( sysarg, moneyTypeMap[dtype] ) < totalCount ) then
		Actor.sendTipmsg( sysarg, Lang.ScriptTips.n00007,ttFlyTip )
		return
	end

	if (Actor.changeMoney( sysarg, dtype, -totalCount ,GameLog.clShopBuyMoney,itemname) ==false )  then
		return false
	end


	local addresult = Item.addItem(sysarg,ritemptr,"back buy",7,amount)
	if addresult then 
		Item.delSellItem(sysarg,ritemptr)
	end

	local npack = DataPack.allocPacket(sysarg,LogicCmd.npcTradeSys.sysId,LogicCmd.npcTradeSys.sub.sNpcTradeShopSellReBuy)  --申请一个数据包
	if (npack == nil) then return end
	DataPack.writeChar(npack,npdId)
	DataPack.writeDouble(npack,ritemguid)
	DataPack.flush(npack)
end



--处理NPC交易
NPCTradeImplementMain = function ( sysarg, sysitemid, msgid, arg ) 
  --3层遍历，找到那个物品--从商店购买东西
  	if(msgid == LogicCmd.npcTradeSys.sub.cNpcTradeBuy) then  
  		local npcId =  DataPack.readByte(arg) 
      	local buyitemid = DataPack.readWord(arg)  --购买的物品ID
		local amount = DataPack.readWord(arg)      --物品的数量 
		--NPC的ID，0表示是背包商店 
		NPCTradeBuy( sysarg, {buyitemid, amount,npcId} )
      	return
  	end
 
  	
    --请求背包商店购买的物品的列表
  	if(msgid == LogicCmd.npcTradeSys.sub.cGetNpcTradeData) then
  		local npcId =  DataPack.readByte(arg) 
    	NPCTradeInfoToClient( sysarg, npcId )
    	return
  	end
  	--[[
  --出售物品给商店 
  	if(msgid == LogicCmd.npcTradeSys.sub.cNpcTradeShopSell) then
  		local npcId =  DataPack.readByte(arg) 
      	local sellitemguid = DataPack.readDouble(arg)  --出售的的物品GUID
		NPCTradeSell( sysarg, {sellitemguid, npcId} ) --出售给商店 
      	return
 	end
 
   --从商店回购 
   	if(msgid == LogicCmd.npcTradeSys.sub.cNpcTradeShopSellReBuy) then
   		local npcId = DataPack.readWord(arg)    
      	local ritemguid = DataPack.readDouble(arg)  --回购的的物品GUID
	    NPCTradeRepurchase( sysarg, {ritemguid,npcId} )
		return 
  	end
  ]]

  	if msgid == LogicCmd.npcTradeSys.sub.cNpcTradeBuyLimitData then
  		SendNPCTradeBuyLimitData( sysarg )
		return 
 	end
end 

SystemHandlerDispatcher.registerSystemHander(BaseTypes.SystemId.npcTradeSystem, NPCTradeImplementMain)
